--[[
	@module Lua语言基础类库
]]

--[[
	计算table的长度
	@t table
]]
local function table_length(t)
	local length = 0;
	if not type(t) == "table" or t == nil then
		return length;
	end
	for key, val in pairs(t) do
		length = length + 1; 
	end
	return length;
end

--获取当前lua宿主的运行路径
local function get_lua_path()
	return _exec_shell("pwd");
end

--获取本机的机器名名称
local function get_host_name()
	return _exec_shell("hostname");
end

--执行shell脚本，仅支持linux
function _exec_shell(cmd)
	local cmd = io.popen(cmd);
	local cmd_r = cmd:read("*all")
	cmd:close();
	return cmd_r;
end

--根据实例和方法名称反射调用
local function reflect(inst, method)
	local exec = inst .. "." .. method .. "()";
	local script="function do_reflect()  return " .. exec .. ";  end";
	assert(loadstring(script))();
	return do_reflect();
end


--[[
	根据实例和方法名称反射调用
	inst实例
	method方法名称
	margs方法参数table
	TODO 返回异常信息
]]
local function reflect_1(inst, method, margs)
	if margs == nil then
		margs = {};
	end
	local m = inst[method];
	if (m == nil) then
		return false;
	end
	return m(unpack(margs));
end

--[[
	tostring
]]
local function to_string(object)
	local str = '';
	if type(object) == "string" then
		return object;
	end
	
	if type(object) == "number" then
		str = tostring(object);
		return str;
	end
	
	if type(object) == "table" then
		local str = "[";
		for i, v in pairs(object) do
			str = str .. i .. "=" .. v .. ",";
		end
		str = str .. "]";
		return str;
	end
end

local function try(func, errorHandler)
	if (errorHandler == nil) then
		local ret, err_msg = xpcall(func, function()  ngx.say(debug.traceback()); end);
		return;
	end
	
	local ret, err_msg = xpcall(func, errorHandler);
end

--[[
	将table类型t2的内容追加到table类型t1的后面
	t1和t2的结构必须是一致的
	调用说明：
	local a = {a=1,b=2};
	local b = {c=1,d=2};
	import(a, b)
	a = {a=1,b=2,c=1,d=2};
	local c = {1,2,3}
	local d = {4,5,6}
	import(c, d)
	c = {1,2,3,4,5,6}
]]
local function import(t1, t2)
	assert(t1, "t1 can not be nil");
	assert(t2, "t2 can not be nil");
	for i, t in pairs(t2) do
		if type(i) == "string" then
			t1[i] = t;
		else
			t1[#t1 + 1] = t;
		end
	end
end

local _M = {  
   table_length = table_length,
   get_lua_path = get_lua_path,
   get_host_name = get_host_name,
   reflect = reflect,
   reflect_1 = reflect_1,
   to_string = to_string,
   import = import,
}

return _M;
